package yawning.mew.cat;

import yawning.mew.ProcEffect.Trigger;
import yawning.mew.character.CharacterModel.AttackResult;
import yawning.mew.sim.SimulationAction;
import yawning.mew.sim.SimulationEventAction;

public class EventRake extends SimulationEventAction {
	CatModelSimState mState;
	private double mAttackPower;
	private double mPCrit;
	boolean mTigersFury;

	EventRake(CatModelSimState state) {
		super(state.mSimUtil);
		mState = state;
	}

	@Override
	public double perform() {
		int cost = mState.getEnergyCost(mState.mModel.rakeCost);
		if (mState.energyTickEv.mEnergy < cost && !mState.oocEv.isUp()) return SimulationAction.ACTION_FAIL;

		AttackResult result = mState.mModel.getYellowResult();

		if (mState.mDebug) mState.DBGF("Rake (%s)", result);

		if (result == AttackResult.MISS) {
			cost = (int) Math.round(cost * 0.2);
			mState.nrRakeMiss++;
		} else if (result == AttackResult.DODGE) {
			cost = (int) Math.round(cost * 0.2);
			mState.nrRakeDodge++;
		} else {
			double damage = mState.mModel.levelDep.getRakeDmg() + mState.mModel.getAttackPower() * mState.mModel.levelDep.getRakeDmgCoeff();

			if (result == AttackResult.CRIT) {
				mState.nrRakeCrit++;
				damage *= mState.mModel.multCrit;
				mState.mSimUtil.triggerProc(Trigger.YELLOWCRIT);
			} else {
				mState.nrRakeHit++;
				mState.mSimUtil.triggerProc(Trigger.YELLOW);
			}

			damage *= mState.getBleedDamageMult();
			damage *= mState.mModel.tier_10_4pc_rakeMult;
			mState.rakeDamage += Math.round(damage);

			if (mState.mDebug) mState.DBGF("  Damage: %d", Math.round(damage));

			mAttackPower = mState.mModel.getAttackPower();
			mPCrit = mState.mModel.getMeleeCritChance();
			mTigersFury = mState.tigersFuryEv.isUp();

			if (!isUp())
				schedule(mState.mModel.getRakeDebuffDuration(), mState.mModel.getRakeTickInterval());
			else
				extendExpiry(mState.mModel.getRakeDebuffDuration() + getNextTickTime() - getExpiryTime());

			mState.onCpGenerator(result == AttackResult.CRIT);
		}

		mState.onOoCConsumer(cost);
		return 1.0;
	}

	@Override
	public void onTick() {
		double damage = mState.mModel.levelDep.getRakeDotDmg() + mAttackPower * mState.mModel.levelDep.getRakeDotCoeff();

		if (mState.mModel.getDotResult(mPCrit) == AttackResult.CRIT) {
			mState.nrRakeDotCrit++;
			damage *= mState.mModel.multCrit;
			mState.mSimUtil.triggerProc(Trigger.DOTCRIT);
		} else {
			mState.nrRakeDotHit++;
			mState.mSimUtil.triggerProc(Trigger.DOT);
		}

		damage *= mState.getBleedDamageMult();
		damage *= mState.mModel.tier_10_4pc_rakeMult;
		damage *= mState.mModel.tier_11_2pc_rakeMult;
		damage *= mTigersFury ? mState.mModel.multTigersFury : 1.0;
		mState.rakeDotDamage += Math.round(damage);

		if (mState.mDebug) mState.DBGF("Rake Tick Damage: %d", Math.round(damage));
	}

	@Override
	public void onExpire() {
		if (mState.mDebug) mState.DBGF("Rake Expiration");
	}

}